Skip to content

fix(create-objectstack): declare pnpm build approvals so a fresh install works on pnpm 11#3119

Merged
os-zhuang merged 1 commit into
mainfrom
claude/brave-torvalds-c0928a
Jul 17, 2026
Merged

fix(create-objectstack): declare pnpm build approvals so a fresh install works on pnpm 11#3119
os-zhuang merged 1 commit into
mainfrom
claude/brave-torvalds-c0928a

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

TL;DR

Publish Smoke was not broken — it was right. It has been red on main since #3100 introduced it because it caught a real, currently-shipping bug on its very first run: npx create-objectstack && pnpm install exits 1 for any user on pnpm 11.

This fixes the product bug, not the gate.

The bug (reproduced against published 15.1.1)

$ npx create-objectstack@latest myapp --skip-install && cd myapp
$ pnpm install          # pnpm 11.13.1, what corepack gives a fresh machine
[ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: better-sqlite3@12.11.1, esbuild@0.28.1
$ echo $?
1

pnpm 11 turned an unapproved dependency build script from a warning into a hard error. The blank template declares no approvals — no packageManager, no pnpm-workspace.yaml, no .npmrc — so the first command a new user runs fails.

Why both approval keys

Neither key alone covers the supported range — measured, not assumed:

pnpm allowBuilds onlyBuiltDependencies
10.0 / 10.15 not recognized required
10.31 (repo pin) recognized (→ only-built-dependencies) redundant
11.13 required — list alone still errors insufficient

The decision this PR makes: the gate stays unpinned

The suggested quick fix was to stamp packageManager into the generated app so it installs with the repo's pinned pnpm 10. That turns the gate green by silencing a true positive — it would test a pnpm no downstream user runs, which is the same "in-repo settings hide the user's real resolution" mistake as #3091, i.e. precisely the failure class this gate exists to catch.

So the smoke's pnpm stays unpinned and keeps testing what a fresh machine gets. The tradeoff is real and recorded in the script header: a new pnpm major can turn this red with no code change here. That is signal, not noise — it means a fresh install is broken for new users and the template needs updating. Exactly what happened here.

Why the gate couldn't see its own blind spot

publish-smoke.sh hand-wrote the app's entire pnpm-workspace.yaml, declaring onlyBuiltDependencies itself. A locally-authored declaration proves nothing about what the template ships — that is how this bug stayed invisible to a gate designed to find it. The script now appends its tarball overrides to the file the template ships, and fails loudly if the scaffold declares no approvals.

Changes

  • templates/blank/pnpm-workspace.yaml (new) — the actual product fix.
  • scripts/publish-smoke.sh — append overrides to the template's file; assert approvals exist; record the no-pin rationale.
  • template-consistency.test.ts — drift ratchet, matching the file's existing purpose.
  • changesetpatch to create-objectstack.

Verification

Ran the real gate locally under CI-identical pnpm resolution (corepack shim: 10.31.0 in-repo, 11.13.1 in the app dir — confirmed, since a plain local run uses global pnpm 10.33 and would not reproduce the failure at all):

== Auth probes (the #3091 failure surface)
  ok — GET /auth/get-session (anonymous) → 200
  ok — POST /auth/sign-up/email → 200
  ok — POST /auth/sign-in/email → 200
== REST CRUD probes (seeded dev admin)
  ok — POST/GET/PATCH/DELETE /data/smoke_app_note → 201/200/200/200
== Scanning server log for error-level output
  ok — no error/fatal log lines
== Publish smoke passed (pack mode)

Controls, so none of this is a tautology:

  • Strip allowBuilds → reproduces the exact CI error (exit 1); restore → clean. The fix is load-bearing.
  • Ratchet controls → template deleted fails 3 tests; allowBuilds removed while onlyBuiltDependencies kept (the exact ObjectLogger file destination silently no-ops in ESM builds #3110 shape) fails exactly 1, with an actionable message.
  • Confirmed pnpm-workspace.yaml survives pnpm pack, so the fix actually ships.
  • eslint clean, 8/8 tests, bash -n clean, pnpm build green.

Found in passing (not fixed here)

pack strips .gitignore from nested template dirs, so scaffolded projects ship no .gitignorenode_modules/ and .env are un-ignored for every new user. Real, pre-existing, out of scope; filed separately.

🤖 Generated with Claude Code

…all works on pnpm 11

`npx create-objectstack myapp && cd myapp && pnpm install` has been exiting 1 on
pnpm 11 — ERR_PNPM_IGNORED_BUILDS for better-sqlite3 and esbuild. pnpm 11 turned
an unapproved dependency build script from a warning into a hard error, and the
blank template declared no approvals at all. Verified against published 15.1.1:
the first command a new user runs fails.

The scaffold now ships a pnpm-workspace.yaml approving the two packages it
depends on building. Both keys are required — neither alone covers the supported
range: pnpm 11 honors only `allowBuilds` (understood back to 10.31), while pnpm
10.0–10.30 understand only `onlyBuiltDependencies`. npm and yarn ignore the file.

This is why Publish Smoke has been red on main since #3100 introduced it. The
gate was never broken: it was correctly reporting a real, shipping product bug
on its first run. Pinning the smoke's pnpm to the repo's `packageManager` would
have turned it green by testing a pnpm no user runs — the same "in-repo settings
hide the user's real resolution" mistake as #3091, which is the exact failure
class this gate exists to catch. So the pnpm version stays unpinned, and the
reasoning is recorded in the script header.

publish-smoke.sh now appends its tarball overrides to the file the template
ships instead of hand-writing the whole thing. It previously declared the
approvals itself, so it proved nothing about what users get — that is how this
bug stayed invisible to a gate designed to find it. It now fails loudly if the
scaffold declares no approvals.

Verified end-to-end under CI-identical resolution (corepack shim: pnpm 10.31.0
in-repo, 11.13.1 in the app dir): full smoke green — clean install, auth
sign-up/sign-in/get-session 200, REST CRUD, no error logs. Negative control:
stripping `allowBuilds` reproduces the exact CI failure; restoring it passes.
The new template-consistency ratchet fails on both regression shapes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 17, 2026 11:52am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Jul 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): create-objectstack.

7 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/skills-reference.mdx (via create-objectstack)
  • content/docs/ai/skills.mdx (via create-objectstack)
  • content/docs/getting-started/index.mdx (via create-objectstack)
  • content/docs/getting-started/your-first-project.mdx (via create-objectstack)
  • content/docs/plugins/packages.mdx (via create-objectstack)
  • content/docs/releases/v15.mdx (via create-objectstack)
  • content/docs/releases/v9.mdx (via create-objectstack)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang merged commit 3a8ce9d into main Jul 17, 2026
20 of 21 checks passed
@os-zhuang
os-zhuang deleted the claude/brave-torvalds-c0928a branch July 17, 2026 11:59
os-zhuang added a commit that referenced this pull request Jul 17, 2026
…-build-approvals comments (#3125)

#3119 cited "#3110" in four comments as the pnpm 11 build-approvals bug. #3110 is an
unrelated, already-closed issue — "ObjectLogger file destination silently no-ops in ESM
builds" (fixed by #3116). The reference was fabricated: the pnpm 11 scaffold breakage was
found while diagnosing the red Publish Smoke gate and has no issue of its own, so the
correct citation is the PR that fixed it, #3119.

Comment-only. It left a wrong pointer in the two places most likely to be read next: the
"why is the smoke's pnpm unpinned" rationale in the script header, and the ratchet
guarding the template. The template pnpm-workspace.yaml and the changeset never cited it,
so nothing user-facing shipped with the bad reference.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
os-zhuang added a commit that referenced this pull request Jul 18, 2026
…before install (#3157)

The Publish Smoke gate died on ERR_PNPM_IGNORED_BUILDS with no way to see
why: the failure was CI-only and every local repro (pnpm 10.31/10.33)
honored the allowlist and exited 0.

The missing fact: the scaffolded app declares no packageManager field (by
design — it must test what a fresh user's pnpm resolves, not this repo's
pin), so with corepack enabled the `pnpm` that installs the app is the
LATEST pnpm (11.x), not the repo-pinned 10.31.0. pnpm 11 makes an
unapproved build script a hard error where pnpm 10 only warned. The app's
build approvals were declared for pnpm 11 in #3119; this adds the missing
visibility so a future red run answers on its own which pnpm ran and
whether it parsed the approvals.

Prints, from inside the app dir right before install: `pnpm --version`,
the build-approval keys pnpm actually resolved (onlyBuiltDependencies via
either allowBuilds or onlyBuiltDependencies), and the pnpm-workspace.yaml
as written. Diagnostics only — never fails the smoke.


Claude-Session: https://claude.ai/code/session_01MN39HnZs8M92iDGqAMcvsK

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant